#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int Juggling(int n, char *str);
int reversal(int n, char *str);
int block_swaping(int n, char *str);
int main(int argc, char *argv[])
{
	int n,i=3;
	char str[100], js[100], ss[100], bs[100];
	memset(str, 0, sizeof(str));
	for (n = 0; n < 26; n++){
		str[n] = 'a'+n;
		for (i = 0; i < strlen(str); i++){
			memcpy(js, str, 100);
			memcpy(ss, str, 100);
			memcpy(bs, str, 100);
			Juggling(i, js);
			reversal(i, ss);
			block_swaping(i, bs);
			if (strcmp(js, ss)){
				printf("Juggling Error\n");
				printf("%s\nss:%s\njs:%s\n", str, ss, js);
			}
			if (strcmp(bs, ss)){
				printf("block swap Error\n");
				printf("%s\nss:%s\njs:%s\n", str, ss, bs);
			}
		}
	}
	return 0;
}
int gcd(int a, int b)
{
	int t;
	if (a > b) {
		t = a; a = b; b = a;
	} 

	while (a != 0) {
		t = a; a = b%a; b = t;
	}

	return b;
}
int Juggling(int n, char *str)
{
	int i, k, j, t, len = strlen(str);
	n = n%len;
	if (n == 0 || len <= 1) return 0;
	for (i = 0; i < gcd(n, len); i++) {
		t = str[i];
		j = i;
		while (1) {
			k = j + n;
			if (k >= len) k -= len;
			if (k == i) break;
			str[j] = str[k];
			j = k;
		}
		str[j] = t;
	}
	return 0;
}

int reverse_str(char *start, char *end)
{
	int i, len = (end-start);
	char p;
	for (i = 0; i < len/2; i++){
		p = start[i];
		start[i] =  start[len-i-1];
		start[len-i-1] = p;
	}
	return 0;
}

int reversal(int n, char *str)
{
	int len = strlen(str);
	n %= len;
	if (n == 0 || len <= 1) return 0;
	reverse_str(str, str+n);
	reverse_str(str+n, str+strlen(str));
	reverse_str(str,  str+strlen(str));
	return 0;
}

int swap(char *str, int s, int k, int n)
{
	int i = 0, t;
	for (i = 0; i < n; i++) {
		t = str[s+i];
		str[s+i] = str[k+i];
		str[k+i] = t;
	}
	return;
}

int block_swaping(int n, char *str)
{
	int len = strlen(str);
	n %= len;
	if (n == 0 || len <= 1) return 0;
	int p = n,  i = n, j = len - n;
	while (i != j){
		if (i > j) {
			swap(str, p-i, p, j);
			i -= j;
		} else {
			swap(str, p-i, p+j-i, i);
			j -= i;
		}
	}
	swap(str, p-i, p, i);
	return 0;
}
